-- Tactician_Objectives.lua
-- Manages the objective system

MAX_OBJECTIVES = 10;
START_COMPLETE_TIME = 1;
MAX_COMPLETE_TIME = 0.5;

Tactician_Objectives = { };							-- Holds all the objectives. Note that the objectives are held using numerical keys

-- Updates the objectives frame
function Tactician_UpdateObjectivesFrame()

	local i,obj;

	-- Sort the objectives in ascending order depending on the priority.
	sort(Tactician_Objectives,function(a,b) return a.priority<b.priority; end);
	
	-- Set the labels for each objective
	for i = 1, MAX_OBJECTIVES do
		obj = getglobal("Tactician_Obj"..i);
		if (Tactician_Objectives[i]) then
			obj:SetText(i..". "..Tactician_Objectives[i].label);
			if (Tactician_Objectives[i].complete) then
				getglobal(obj:GetName().."_Check"):SetChecked(1);
				obj:SetTextColor(0.5,0.5,0.5);
			else
				getglobal(obj:GetName().."_Check"):SetChecked(nil);
				obj:SetTextColor(0.4,0.6,0.8);
			end
			obj:Show();
		else
			obj:Hide();
			obj:SetAlpha(1);
		end
	end
	
	-- Resize the objectives frame
	if (#Tactician_Objectives > 0) then
		Tactician_ObjectivesFrame:SetHeight(Tactician_Obj1:GetHeight()*#Tactician_Objectives+4);
		Tactician_ObjectivesFrame:Show();
	else
		Tactician_ObjectivesFrame:Hide();
	end

end

--[[
obj should be a table with the following fields:
id = An id with which to reference this objective.
label = The label to show in the objectives box.
priority = The lower this number, the more important this objective is (appears higher in the list).
desc = (Optional) The longer description to show in the tooltip.
icon = (Optional) An icon path to show beside the label.
time = Time, in seconds, before the objective is completed automatically. -1 for untimed objective.
unique = (Optional) If set, only one objective with this particular id is allowed.
type = (Optional) This comes soon.
]]--
function Tactician_AddObjective(obj)

	if (type(obj) ~= "table") then
		return;
	end
	
	if (obj.unique) then
		-- Objective is unique. Make sure there isn't another one.
		local i;
		for i = 1, #Tactician_Objectives do
			if (Tactician_Objectives[i].id == obj.id) then
				-- Match found. Don't add the objective.
				return;
			end
		end
	end
	
	-- !! VALIDATE THE TABLE!
	obj.elapsed = 0;
	obj.completeTime = 0;
	tinsert(Tactician_Objectives,obj);
	
	Tactician_UpdateObjectivesFrame();

end

function Tactician_CompleteObjectiveByIndex(index)

	Tactician_Objectives[index].complete = 1;
	
	Tactician_UpdateObjectivesFrame();

end

-- Marks an objective as complete
function Tactician_CompleteObjective(id)

	local i;
	for i = #Tactician_Objectives, 1, -1 do
		if (Tactician_Objectives[i].id == id) then
			-- ID matches. Mark as complete
			DEFAULT_CHAT_FRAME:AddMessage("Completed Objective: " .. Tactician_Objectives[i].label);
			Tactician_Objectives[i].complete = 1;
		end
	end
	
	Tactician_UpdateObjectivesFrame();
	-- The idea is to tick the checkbox for the objective and fade the objective out after which it is removed.

end

function Tactician_RemoveObjectiveByIndex(index)

	tremove(Tactician_Objectives,index);
	
	Tactician_UpdateObjectivesFrame();

end

-- Removes the objective from the list
function Tactician_RemoveObjective(id)

	local i;
	for i = #Tactician_Objectives, 1, -1 do 
		if (Tactician_Objectives[i].id == id) then
			-- ID matches. Remove.
			tremove(Tactician_Objective,i);
		end
	end
	
	Tactician_UpdateObjectivesFrame();

end

-- OnUpdate for the timer frame
function Tactician_ObjectiveTimerUpdate(elapsed)

	local i,obj;
	for i = #Tactician_Objectives,1,-1 do
		Tactician_Objectives[i].elapsed = Tactician_Objectives[i].elapsed + elapsed;
		if (Tactician_Objectives[i].complete) then
			-- Objective is complete. Add time to its completeTime
			Tactician_Objectives[i].completeTime = Tactician_Objectives[i].completeTime + elapsed;
			obj = getglobal("Tactician_Obj"..i);
			obj:SetAlpha((Tactician_Objectives[i].completeTime >= START_COMPLETE_TIME) and (1 - (Tactician_Objectives[i].completeTime - START_COMPLETE_TIME) / MAX_COMPLETE_TIME) or (1));
			if (Tactician_Objectives[i].completeTime >= MAX_COMPLETE_TIME + START_COMPLETE_TIME) then
				Tactician_RemoveObjectiveByIndex(i);
				obj:SetAlpha(1);
			end
		elseif (Tactician_Objectives[i].time > -1) and (Tactician_Objectives[i].elapsed >= Tactician_Objectives[i].time) then
			-- Is a timed objective and it expired. Complete it.
			Tactician_CompleteObjectiveByIndex(i);
		elseif (Tactician_Objectives[i].time > -1) then
			-- It's a timed objective but it hasn't expired yet. Update the widget to show the time remaining.
			getglobal("Tactician_Obj"..i):SetText(i .. ". " .. Tactician_Objectives[i].label .. " (" .. ceil(Tactician_Objectives[i].time - Tactician_Objectives[i].elapsed) .. " secs)");
		end
	end

end

